package cn.wen.yinxiu.product.service.impl;

import cn.wen.yinxiu.common.base.holder.UserDTO;
import cn.wen.yinxiu.common.base.holder.UserHolder;
import cn.wen.yinxiu.common.convention.result.ResultEntity;
import cn.wen.yinxiu.common.enums.DelEnum;
import cn.wen.yinxiu.common.enums.StatusEnum;
import cn.wen.yinxiu.common.to.es.WorksEsModel;
import cn.wen.yinxiu.common.to.order.OrderTO;
import cn.wen.yinxiu.common.to.product.SkuInfoTO;
import cn.wen.yinxiu.common.toolkit.StringUtils;
import cn.wen.yinxiu.product.dao.StockSkuDao;
import cn.wen.yinxiu.product.entity.AttrEntity;
import cn.wen.yinxiu.product.entity.StockOrderTaskDetailEntity;
import cn.wen.yinxiu.product.entity.StockOrderTaskEntity;
import cn.wen.yinxiu.product.feign.FileFeignService;
import cn.wen.yinxiu.product.feign.OrderFeignService;
import cn.wen.yinxiu.product.feign.WorksFeignService;
import cn.wen.yinxiu.product.service.*;
import cn.wen.yinxiu.product.vo.*;
import com.alibaba.fastjson.TypeReference;
import com.google.gson.Gson;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.wen.yinxiu.common.toolkit.PageUtils;
import cn.wen.yinxiu.common.toolkit.Query;

import cn.wen.yinxiu.product.dao.SkuInfoDao;
import cn.wen.yinxiu.product.entity.SkuInfoEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import static cn.wen.yinxiu.common.constant.Constant.WorksType.Video;


@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {

    @Autowired
    private FileFeignService fileFeignService;

    @Autowired
    private SkuInfoDao skuInfoDao;

    @Autowired
    private AttrService attrService;

    @Autowired
    private WorksFeignService worksFeignService;

    @Autowired
    private StockOrderTaskService stockOrderTaskService;

    @Autowired
    private OrderFeignService orderFeignService;

    @Autowired
    private StockSkuService stockSkuService;

    @Autowired
    private StockOrderTaskDetailService stockOrderTaskDetailService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                new QueryWrapper<SkuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public boolean saveSkuInfo(MultipartFile[] imageList, MultipartFile[] skuDescList, String skuInfo) {
        int res = 0;
        try {
            // 1.远程调用文件上传服务
            ResultEntity<String> imageListRes = fileFeignService.uploadCloudFile(Arrays.asList(imageList));
            String imagePathList = imageListRes.getData();
            // 2.远程调用文件上传服务（上传照片详情列表）
            ResultEntity<String> skuDescListRes = fileFeignService.uploadCloudFile(Arrays.asList(skuDescList));
            String skuDescPathList = skuDescListRes.getData();
            // 3.解析对应的JSON数据
            Gson gson = new Gson();
            AddSkuInfoVO addSkuInfoVO = gson.fromJson(skuInfo, AddSkuInfoVO.class);
            // 4.根据对应的数据格式进行解析

            // 4.补充相关信息 根据作品类型存储记录
            UserDTO user = UserHolder.getUser();
            SkuInfoEntity target = new SkuInfoEntity();
            BeanUtils.copyProperties(addSkuInfoVO, target);
            target.setImageUrl(imagePathList);
            target.setSkuDesc(skuDescPathList);
            target.setSaleCount(0L);
            target.setIsDeleted(DelEnum.NORMAL.code());
            target.setStatus(StatusEnum.NORMAL_USE.code());
            // 6.将作品数据存入数据库
            res = skuInfoDao.insert(target);
            // 4.2.解析商品的属性
            String[] attrKeyValue = addSkuInfoVO.getAttrList().split(";");
            List<AttrEntity> attrList = new ArrayList<>();
            for (String attr : attrKeyValue) {
                AttrEntity attrTarget = new AttrEntity();
                String[] attrKeyValues = attr.split(":");
                attrTarget.setSkuId(target.getSkuId());
                attrTarget.setAttrName(attrKeyValues[0]);
                attrTarget.setValue(attrKeyValues[1]);
                attrTarget.setStatus(StatusEnum.NORMAL_USE.code());
                attrList.add(attrTarget);
            }
            // 7. TODO 删除相对于缓存
            // 8.添加到attr中
            boolean b = attrService.saveBatch(attrList);
            // 9.远程服务调用WorksService将当前作品ID存入到作品数据中
            worksFeignService.addWorksProduct(addSkuInfoVO.getWorksId(), target.getSkuId());
        } catch (Exception e) {
            // 如果抛出异常则会回滚事务 则需要删除文件  这个则调用
            // TODO 为了保证删除成功 则将删除操作发送到消息队列中实现
            e.printStackTrace();
        }
        return res > 0;
    }

    @Override
    public boolean deleteSkuInfoByWorks(Long productId, Long worksId) {
        // 1.删除商品信息
        SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
        skuInfoEntity.setSkuId(productId);
        skuInfoEntity.setIsDeleted(DelEnum.DELETE.code());
        int res = skuInfoDao.updateById(skuInfoEntity);
        // 2.将商品ID从作品中移除
        worksFeignService.deleteWorksProductById(worksId).getData();
        return res > 0;
    }

    @Override
    public boolean updateSkuInfoByWorks(MultipartFile[] imageList, MultipartFile[] skuDescList, String skuInfo) {
        // 1.远程调用文件上传服务
        // 判断是否为空
        SkuInfoEntity target = new SkuInfoEntity();
        if (imageList != null && imageList.length > 0) {
            ResultEntity<String> imageListRes = fileFeignService.uploadCloudFile(Arrays.asList(imageList));
            String imagePathList = imageListRes.getData();
            target.setImageUrl(imagePathList);

        }
        // 2.远程调用文件上传服务（上传照片详情列表）
        if (skuDescList != null && skuDescList.length > 0) {
            ResultEntity<String> skuDescListRes = fileFeignService.uploadCloudFile(Arrays.asList(skuDescList));
            String skuDescPathList = skuDescListRes.getData();
            target.setSkuDesc(skuDescPathList);
        }
        // 3.解析对应的JSON数据
        Gson gson = new Gson();
        UpdateSkuInfoVO updateSkuInfoVO = gson.fromJson(skuInfo, UpdateSkuInfoVO.class);
        // 4.根据对应的数据格式进行解析
        // 4.补充相关信息 根据作品类型存储记录
        BeanUtils.copyProperties(updateSkuInfoVO, target);
        // 4.2.解析商品的属性
        String[] attrKeyValue = updateSkuInfoVO.getAttrList().split(";");
        List<AttrEntity> attrList = new ArrayList<>();
        for (String attr : attrKeyValue) {
            AttrEntity attrTarget = new AttrEntity();
            String[] attrKeyValues = attr.split(":");
            attrTarget.setSkuId(target.getSkuId());
            attrTarget.setAttrName(attrKeyValues[0]);
            attrTarget.setValue(attrKeyValues[1]);
            attrTarget.setStatus(StatusEnum.NORMAL_USE.code());
            attrList.add(attrTarget);
        }
        // 6.将作品数据存入数据库
        boolean res = skuInfoDao.updateById(target) > 0;
        // 7. TODO 删除相对于缓存
        // 8. 先删除掉Attr中的数据 添加到attr中
        attrService.remove(new QueryWrapper<AttrEntity>().eq("sku_id", target.getSkuId()));
        boolean b = attrService.saveBatch(attrList);
        return res;
    }

    @Override
    public SkuInfoVO getSkuInfoByProductId(Long productId) {
        // 1.通过商品Id获取商品的基本信息
        SkuInfoEntity skuInfoEntity = skuInfoDao.selectById(productId);
        // 需要替换信息 同时需要解析照片信息
        SkuInfoVO target = new SkuInfoVO();
        BeanUtils.copyProperties(skuInfoEntity, target);
        // 解析照片信息
        if (StringUtils.isNotEmpty(skuInfoEntity.getImageUrl())) {
            target.setImageUrlList(Arrays.asList(skuInfoEntity.getImageUrl().split(";")));
        }
        if (StringUtils.isNotEmpty(skuInfoEntity.getSkuDesc())) {
            target.setSkuDescImageList(Arrays.asList(skuInfoEntity.getSkuDesc().split(";")));
        }
        // 2.获取商品的属性信息  通过商品ID 获取属性信息
        List<AttrInfoVO> attrInfoList = attrService.getAttrInfoListBySkuId(productId);
        target.setAttrList(attrInfoList);
        return target;
    }

    @Override
    public SkuInfoTO getSkuInfoById(Long skuId) {
        // 1.通过商品Id获取商品的基本信息
        SkuInfoEntity skuInfoEntity = skuInfoDao.selectById(skuId);
        // 需要替换信息 同时需要解析照片信息
        SkuInfoTO target = new SkuInfoTO();
        BeanUtils.copyProperties(skuInfoEntity, target);
        return target;
    }

    @Override
    public void unlockStock(StockLockedVO to) {
        // 库存工作单的id
        StockDetailVO detail = to.getDetailVO();
        Long detailId = detail.getId();

        /**
         * 解锁
         * 1、查询数据库关于这个订单锁定库存信息
         *   有：证明库存锁定成功了
         *      解锁：订单状况
         *          1、没有这个订单，必须解锁库存
         *          2、有这个订单，不一定解锁库存
         *              订单状态：已取消：解锁库存
         *                      已支付：不能解锁库存
         */
        StockOrderTaskDetailEntity taskDetailInfo = stockOrderTaskDetailService.getById(detailId);
        if (taskDetailInfo != null) {
            // 查出y_stock_order_task工作单的信息
            Long id = to.getId();
            StockOrderTaskEntity orderTaskInfo = stockOrderTaskService.getById(id);
            // 获取订单号查询订单状态
            String orderSn = orderTaskInfo.getOrderSn();
            // 远程查询订单信息
            OrderTO orderTo = orderFeignService.getOrderStatus(orderSn).getData();
            if (orderTo != null) {
                // 订单数据返回成功
                // 判断订单状态是否已取消或者支付或者订单不存在
                if (orderTo == null || orderTo.getStatus() == 4) {
                    // 订单已被取消，才能解锁库存
                    if (taskDetailInfo.getLockStatus() == 1) {
                        // 当前库存工作单详情状态1，已锁定，但是未解锁才可以解锁
                        unLockStock(detail.getSkuId(), detail.getSkuNum(), detailId);
                    }
                }
            } else {
                //消息拒绝以后重新放在队列里面，让别人继续消费解锁
                //远程调用服务失败
                throw new RuntimeException("远程调用服务失败");
            }
        } else {
            //无需解锁
        }
    }

    /**
     * 防止订单服务卡顿，导致订单状态消息一直改不了，库存优先到期，查订单状态新建，什么都不处理
     * 导致卡顿的订单，永远都不能解锁库存
     * @param orderTo
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void unlockStock(OrderTO orderTo) {

        String orderSn = orderTo.getOrderSn();
        // 查一下最新的库存解锁状态，防止重复解锁库存
        StockOrderTaskEntity orderTaskEntity = stockOrderTaskService.getOrderTaskByOrderSn(orderSn);

        // 按照工作单的id找到所有 没有解锁的库存，进行解锁
        Long id = orderTaskEntity.getId();
        List<StockOrderTaskDetailEntity> list = stockOrderTaskDetailService.list(new QueryWrapper<StockOrderTaskDetailEntity>()
                .eq("task_id", id).eq("lock_status", 1));

        for (StockOrderTaskDetailEntity taskDetailEntity : list) {
            unLockStock(taskDetailEntity.getSkuId(),
                    taskDetailEntity.getSkuNum(),
                    taskDetailEntity.getId());
        }

    }

    /**
     * 解锁库存的方法
     * @param skuId
     * @param num
     * @param taskDetailId
     */
    public void unLockStock(Long skuId, Integer num,Long taskDetailId) {

        // 库存解锁
        stockSkuService.unLockStock(skuId, num);

        // 更新工作单的状态
        StockOrderTaskDetailEntity taskDetailEntity = new StockOrderTaskDetailEntity();
        taskDetailEntity.setId(taskDetailId);
        // 变为已解锁
        taskDetailEntity.setLockStatus(2);
        stockOrderTaskDetailService.updateById(taskDetailEntity);

    }

}